package org.yihang.common.hibernate;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.yihang.common.query.Page;

// T 表示实体类型 ， ID 表示主键类型
public interface GenericDao<T, ID extends Serializable> {

	/**
	 * 保存实体
	 * 
	 * @param entity
	 * @return
	 */
	public ID save(T entity);

	/**
	 * 更新实体
	 * 
	 * @param entity
	 */
	public void update(T entity);

	/**
	 * 删除实体
	 * 
	 * @param id
	 */
	public void delete(ID id);

	/**
	 * 按ID查询实体
	 * 
	 * @param id
	 * @return
	 */
	public T findOne(ID id);

	/**
	 * 查询所有实体
	 * 
	 * @return
	 */
	public List<T> findAll();
	
	// Object ... == Object[]
	// findList(1, 10, ' from User where username = ? and id = ?', "张三", 1);
	public List<T> findList(Integer pageNo, Integer pageSize, String hql, Object... params);

	/**
	 * 根据hql查询实体 hql使用命名占位符, map中key: 命名占位符, value: 占位符实际值
	 * 
	 * @param pageNo
	 * @param pageSize
	 * @param hql
	 * @param params
	 * @return
	 */
	// map.put("n", "张三");
	// map.put("i", 1);
	// findList(1, 10, ' from User where username = :n and id = :i', );
	public List<T> findList(Integer pageNo, Integer pageSize, String hql, Map<String, Object> params);

	/**
	 * 根据hql, counthql查询实体, pageNo:页号, pageSize:页面大小, 数组中包含了?占位符的实际值; 返回分页对象
	 * 
	 * @param pageNo
	 * @param pageSize
	 * @param hql
	 * @param counthql
	 * @param params
	 * @return
	 */
	// hql = from User
	// counthql = select count(*) from User
	public Page<T> findPage(int pageNo, int pageSize, String hql, String counthql, Object... params);

	/**
	 * 根据hql, counthql查询实体, pageNo:页号, pageSize:页面大小, List中包含了?占位符的实际值; 返回分页对象
	 * 
	 * @param pageNo
	 * @param pageSize
	 * @param hql
	 * @param counthql
	 * @param params
	 * @return
	 */
	public Page<T> findPage(int pageNo, int pageSize, String hql, String counthql, List<Object> params);

	/**
	 * 根据hql, counthql查询实体, pageNo:页号, pageSize:页面大小, map中key: 命名占位符,
	 * value:占位符实际值; 返回分页对象
	 * 
	 * @param pageNo
	 * @param pageSize
	 * @param hql
	 * @param counthql
	 * @param params
	 * @return
	 */
	public Page<T> findPage(int pageNo, int pageSize, String hql, String counthql, Map<String, Object> params);

	/**
	 * 根据hql查询单个实体
	 * 
	 * @param hql
	 * @param objects
	 * @return
	 */
	public T findOne(String hql, Object... objects);

	/**
	 * 根据hql查询单个实体
	 * 
	 * @param hql
	 * @param params
	 * @return
	 */
	public T findOne(String hql, Map<String, Object> params);

	/**
	 * 根据hql查询单个值，注意这里用了其他类型泛型，不必和实体类型一致
	 * 
	 * @param c
	 * @param hql
	 * @param objects
	 * @return
	 */
	public <W> W findOne(Class<W> c, String hql, Object... objects);

	/**
	 * 根据hql查询单个值，注意这里用了其他类型泛型，不必和实体类型一致
	 * 
	 * @param c
	 * @param hql
	 * @param params
	 * @return
	 */
	public <W> W findOne(Class<W> c, String hql, Map<String, Object> params);
	
}
